package com.naodong.shenluntiku.mvp.view.widget;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

import com.naodong.shenluntiku.R;


/**
 * Created by hujie on 17/2/24.
 */

public class PointView extends View {
    Paint mPaint;
    Paint mOuterPaint;//外面圆画笔
    Paint mCirclePaint;//内圆画笔
    int outerColor;//外圆颜色
    int innerColor;//内圆颜色
    int whiteColor;
    int mPointArcWidth;
    int mDotPointWidth;
    int mWidth;
    int mHeight;
    int mSpace;
    float mAngel;
    float mStartAngel = 0;
    float mProgress;
    float mRadius;
    // 动效过程监听器
    private ValueAnimator.AnimatorUpdateListener mUpdateListener;
    private Animator.AnimatorListener mAnimatorListener;
    //过程动画
    private ValueAnimator mValueAnimator;
    // 用于控制动画状态转换
    private Handler mAnimatorHandler;
    // 默认的动效周期 2s
    private int defaultDuration = 2000;

    public PointView(Context context) {
        super(context);
        initView(context);
    }

    public PointView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initView(context);
    }

    public PointView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context);
    }


    private void initView(Context context) {
        mPaint = new Paint();
        mOuterPaint = new Paint();
        mCirclePaint = new Paint();
        outerColor = getResources().getColor(R.color.point_outercolor);
        innerColor = getResources().getColor(R.color.point_innercolor);

        whiteColor = getResources().getColor(R.color.colorWhite);
        mPointArcWidth = getResources().getDimensionPixelSize(R.dimen.point_dp);
        mSpace = getResources().getDimensionPixelSize(R.dimen.dp_4);
        mDotPointWidth = getResources().getDimensionPixelSize(R.dimen.point_circle_dp);

    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        mRadius = getWidth() / 2 - mPointArcWidth / 2 - mSpace;
        mHeight = getHeight();
        mWidth = getWidth();
        canvas.rotate(-90,mWidth/2,mHeight/2);
        drawPointInsideArc(canvas);
        drawPointOuterArc(canvas);
        drawDotPoint(canvas);
    }

    /**
     * 画内圆环
     */
    private void drawPointInsideArc(Canvas canvas) {

        float centerX = getWidth() / 2;
        float centerY = getHeight() / 2;

        mPaint.setColor(innerColor);
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(mPointArcWidth);
        canvas.drawCircle(centerX, centerY, mRadius, mPaint);
    }

    /**
     * 画小圆点
     * @param canvas
     */
    private void drawDotPoint(Canvas canvas) {
        if (mAngel != 0) {
            mCirclePaint.setColor(outerColor);
            mCirclePaint.setAntiAlias(true);
            mCirclePaint.setStyle(Paint.Style.FILL);
            float cx = (float) (mWidth / 2 + (mRadius) * Math.cos((mStartAngel + mAngel) * Math.PI / 180));
            float cy = (float) (mHeight / 2 + (mRadius) * Math.sin((mStartAngel + mAngel) * Math.PI / 180));
            canvas.drawCircle(cx, cy, mDotPointWidth, mCirclePaint);
        }
    }

    /**
     * 画外环
     * @param canvas
     */
    private void drawPointOuterArc(Canvas canvas) {
        float cx = (float) (mWidth / 2 + (mRadius) * Math.cos((mStartAngel + mAngel) * Math.PI / 180));
        float cy = (float) (mHeight / 2 + (mRadius) * Math.sin((mStartAngel + mAngel) * Math.PI / 180));
        Shader shader;
        if (mProgress <= 60) {
            shader = new LinearGradient(mWidth, mHeight/2, cx, cy, innerColor, outerColor, Shader.TileMode.MIRROR);
        } else {
            shader = new SweepGradient(mWidth / 2, mHeight / 2, innerColor, outerColor);
        }
        mOuterPaint.setShader(shader);
        mOuterPaint.setAntiAlias(true);
        mOuterPaint.setStyle(Paint.Style.STROKE);
        mOuterPaint.setStrokeWidth(mPointArcWidth);

        RectF rectF = new RectF(mWidth / 2 - mRadius, mHeight / 2 - mRadius, mWidth / 2 + mRadius, mHeight / 2 + mRadius);
        float startAngel = mStartAngel;
        float endAngel = mAngel;
        canvas.drawArc(rectF, startAngel, endAngel, false, mOuterPaint);


    }


    public void setProgress(float progress) {

        this.mProgress = progress;
        initListener();
        initHandler();
        initAnimator();
        postDelayed(() -> mValueAnimator.start(), 100);

    }


    private void initListener() {
        mUpdateListener = animation -> {
            mAngel = (float) animation.getAnimatedValue() * mProgress * 18 / 5;
            invalidate();

        };

        mAnimatorListener = new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                // getHandle发消息通知动画状态更新
                mAnimatorHandler.sendEmptyMessage(0);
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        };
    }

    private void initHandler() {
        mAnimatorHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                switch (msg.what) {
                    case 0:
                        mValueAnimator.removeAllUpdateListeners();
                        mValueAnimator.removeAllListeners();
                        break;
                    case 1:
                        invalidate();
                        break;
                }

            }
        };
    }

    private void initAnimator() {
        mValueAnimator = ValueAnimator.ofFloat(0, 1).setDuration(defaultDuration);

        mValueAnimator.addUpdateListener(mUpdateListener);

        mValueAnimator.addListener(mAnimatorListener);
    }
}
